<?php
require_once 'Junction/Query.php';
require_once 'Junction/Utils/Reflection.php';
require_once 'Junction/Utils/Strings.php';
require_once 'Junction/Tracker.php';

/**
 * Represent a single SQL table.
 * 
 */
class Junction_Mapping_Table {
	
	private $_name;
	private $_key;
	private $_properties;
	private $_columns;
	
	/**
	 * @param String $name
	 */
	public function __construct($name) {
		$this->_name = $name;
		$this->_properties = array();
		$this->_columns = array();
	}
	
	/**
	 * @param String $property
	 * @param String $column
	 */
	public function addKey($property, $column) {
		$this->_key = $property;
		$this->addColumn($property, $column);
	}
	
	/**
	 * @param String $property
	 * @param String $column
	 */
	public function addColumn($property, $column) {
		$this->_properties[$property] = $column;
		$this->_columns[$column] = $property;
	}
	
	/**
	 * @param Junction_Query $builder
	 * @param Object $object
	 * @return Junction_Query
	 */
	public function buildQueryUsing(Junction_Query $builder, $object = null) {
		// TODO handle null object case
		$builder->bindTable($this->_name);
		foreach ($this->_properties as $property => $column) {
			$value = null;
			if (isset($object)) {
				$value = Junction_Utils_Reflection::getValueFor($object, $property);
			}
			if (Junction_Tracker::hasPropertyChanged($object, $property, $value)) {
			    $builder->bindColumn($column, $value);
			}
		}
		return $builder;
	}
	
	public function translateQuery($query) {
		foreach ($this->_properties as $property => $column) {
			$query = Junction_Utils_Strings::replaceAll($query, $property, $column);
		}
		return $query;
	}
	
	public function getName() {
	    return $this->_name;
	}
	
	/**
	 * @return String
	 */
	public function getKeyProperty() {
		return $this->_key;
	}
	
	/**
	 * @return Iterator
	 */
	public function getProperties() {
		return new ArrayIterator(array_keys($this->_properties));
	}
	
	/**
	 * @param String $property
	 * @return String
	 */
	public function propertyToColumn($property) {
		if ($this->contains($property)) {
			return $this->_properties[$property];
		}
		return null;
	}
	
	/**
	 * @param String $column
	 * @return String
	 */
	public function columnToProperty($column) {
		if (isset($this->_columns[$column])) {
			return $this->_columns[$column];
		}
		return null;
	}
	
	/**
	 * @param String $property
	 * @return boolean
	 */
	public function contains($property) {
		return (isset($this->_properties[$property]));
	}
}
?>